package com.gitee.wsl.collections.map


open class ConvertingMutableMap<K, From, To>(
    private val delegate: MutableMap<K, From>,
    private val convertTo: From.() -> To,
    private val convert: To.() -> From
) : MutableMap<K, To> {

    open fun Collection<To>.convert(): Collection<From> = map { it.convert() }
    open fun Collection<From>.convertTo(): Collection<To> = map { it.convertTo() }

    override fun get(key: K): To? {
        return delegate[key]?.convertTo()
    }

    override fun put(key: K, value: To): To? {
        return delegate.put(key,value.convert())?.convertTo()
    }

    override val size: Int
        get() = delegate.size


    override fun clear() {
        delegate.clear()
    }

    override fun containsKey(key: K): Boolean  = delegate.containsKey(key)

    override fun containsValue(value: To): Boolean = delegate.containsValue(value.convert())

    override fun putAll(from: Map<out K, To>)
            = delegate.putAll(from.map { it.key to it.value.convert() })

    override fun isEmpty(): Boolean  = delegate.isEmpty()

    override fun remove(key: K): To? = delegate.remove(key)?.convertTo()

    override val keys: MutableSet<K>
        get() = delegate.keys

     fun remove(key: K, value: To): Boolean {
        if(get(key) == value){
            remove(key)
            return true
        }
        return false
    }

    override val values: MutableCollection<To>
        get() = delegate.values.map(convertTo).toMutableList()

    override val entries: MutableSet<MutableMap.MutableEntry<K, To>>
        get() = delegate.entries.map {
            object :MutableMap.MutableEntry<K, To>{
                override val key: K
                    get() = it.key

                override val value: To
                    get() = it.value.convertTo()

                override fun setValue(newValue: To): To {
                     return put(key,newValue)?:newValue
                }
            }
        }.toMutableSet()

}
